/* Copyright (c) 2009-2010, Sean A.O. Harney <sharney3@gmail.com> */

%{
#include "omf-omf_parse.h"
#include "omf.h"
extern void yyerror (const char *error);
%}

%option noyywrap 
%option yylineno 
%option nounput

id [a-zA-Z_][a-zA-Z0-9_]*
dollarid \$[0-9\$]
nint -[0-9]+
pint [0-9]+
float ([0-9]+\.[0-9]+)|([0-9]+(\.[0-9]+)?[eE]-?[0-9]+)
string \"(\\.|[^\\"\n])*\"|\'(\\.|[^\\'\n])*\'
bool true|false
runawaystring \"\.*[^\"]*\.*\n
ws [ \t\r\n]+
comment #[^\n]*\n
%%

%{
#ifdef ARCH_X86_64
			if(0) goto find_rule; /* added in .l file to stop warning find_rule declared but not used in generated lexer C */
			    //was happening with centos x86_64.
			    //with yylineno, 
			    //but find_rule undefined on x86 with
			    // or without fin_rule
#endif
%}

"fuzzdata"	{ return TOK_FUZZDATA; }
"function"	{ return TOK_FUNCTION; }
"repeat"	{ return TOK_REPEAT; }
"if"		{ return TOK_IF; }
"return"	{ return TOK_RETURN; }
"var"		{ return TOK_VAR; }
"pattern"	{ return TOK_PATTERN; }
"file"		{ return TOK_FILE; }
"random"	{ return TOK_RANDOM; }
"target"	{ return TOK_TARGET; }
"command"	{ return TOK_COMMAND; }
"dl"		{ return TOK_DL; }
"stdin"		{ return TOK_STDIN; }
"socket"	{ return TOK_SOCKET; }
"tcp"		{ return TOK_TCP; }
"udp"		{ return TOK_UDP; }
"raw"		{ return TOK_RAW; }
"send"		{ return TOK_SEND; }
"expect"	{ return TOK_EXPECT; }
"flag"		{ return TOK_FLAG; }
"termination"	{ return TOK_TERMINATION; }
"exit"		{ return TOK_EXIT; }
"signal"	{ return TOK_SIGNAL; }
"any"		{ return TOK_ANY; }
"memory"	{ return TOK_MEMORY; }
"size"		{ return TOK_SIZE; }
"rss"		{ return TOK_RSS; }
"pss"		{ return TOK_PSS; }
"start"		{ return TOK_START; }
"print"		{ return TOK_PRINT; }
"include"	{ return TOK_INCLUDE; }
"shell"		{ return TOK_SHELL; }
"sleep"		{ return TOK_SLEEP; }
"+"		{ return TOK_PLUS; }
"-"		{ return TOK_DASH; }
"*"		{ return TOK_ASTERISK; }
"/"		{ return TOK_SLASH; }
";"		{ return TOK_SEMICOLON; }
","		{ return TOK_COMMA; }
"("		{ return TOK_OPENPAREN; }
")"		{ return TOK_CLOSEPAREN; }
"{"		{ return TOK_OPENBRACE; }
"}"		{ return TOK_CLOSEBRACE; }
"="		{ return TOK_EQUALS; }


{dollarid}	{
    			yylval.string_val = checked_strdup(yytext);
			//printf("dollarid %s\n", yytext);
			return TOK_DOLLARID;
		}

{nint}		{
			/* NOTE: there is no limit on size of string, will atoi always return something? */
			yylval.int_val = atoi(yytext);
			return TOK_NINT_CONST;
		}

{pint}		{
			yylval.int_val = atoi(yytext);
			return TOK_PINT_CONST;
		}

{float}		{
			yylval.float_val = atof(yytext);
			return TOK_FLOAT_CONST;
		}

{string}	{
		int string_len;	
	 	/* yyleng == strlen(yytext); */

			/* This shouldn't happen! "" or '' is the smallest yytext. */
			if(yyleng < 2)
			    yyerror("yyleng < 2. This shouldn't happen!"); 

			/* yyleng - 2 for the enclosing quotes("" or ''). Actual length of char array (not including ASCII NUL
			 * character is 2 smaller than yyleng. */
			string_len = yyleng - 2; 



			yylval.string_val = (char *)checked_malloc(string_len * 2 + 1); 
			strncpy(yylval.string_val,yytext + 1, yyleng -2);
			yylval.string_val[yyleng - 2] = '\0';
			return TOK_STRING_CONST;
		}

{bool}		{
 
    			yylval.bool_val = strcmp(yytext,"true") ? false : true;
			return TOK_BOOL_CONST;
		}

{runawaystring}	{ yyerror("runaway string"); }

{id}		{
/* NOTE: this singleline comment produced warning or error with x86_64 lex;   // -2"+1\0
			 * TODO: reproduce and file bug report. */


			yylval.string_val = checked_strdup(yytext);
			return TOK_ID;
    		}

{ws}		{ /* Ignore white spaces */ } ; 
{comment}	{ /* Ignore white spaces */ } ; 
. 		{ yyerror("unrecognized character"); 
		 }

%%
